﻿using System.IO;

namespace MLSharp.SupportVectorMachines
{
	/// <summary>
	/// Converts from <see cref="IDataSet"/> to a file
	/// format that libSVM's C command-line tools can 
	/// parse.
	/// </summary>
	public static class LibSvmDataWriter
	{
		/// <summary>
		/// Writes the data set to the specified file.
		/// </summary>
		/// <param name="dataSet"></param>
		/// <param name="fileName"></param>
		public static void WriteData(IDataSet dataSet, string fileName)
		{
			//Loop through and write the data in the format that libSVM likes
			using (StreamWriter writer = File.CreateText(fileName))
			{
				foreach (Instance instance in dataSet.Instances)
				{
					//First, write the class value
					writer.Write("{0} ", instance.Values[dataSet.TargetAttributeIndex] > 0 ? "+1" : "-1");

					//Then, loop through and write all non-label attributes.
					for (int i = 0; i < dataSet.Attributes.Count; i++)
					{
						//Skip the target attribute.
						if (i == dataSet.TargetAttributeIndex)
						{
							continue;
						}

						double value = (dataSet.Attributes[i].IsNumeric() || dataSet.Attributes[i].PossibleValues.Length != 2)
							//The instance is either numeric or not a binary set
							? instance.Values[i]
							//Otherwise, the instance is binary.
							: (instance.Values[i] == 0 ? -1.0 : 1.0);

						writer.Write("{0}:{1} ", i, value);
					}

					writer.WriteLine();
				}
			}
		}

	}
}
